package com.kuaiyin.utils;

import org.springframework.beans.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 对象转换工具类，用于 Entity、DTO、VO 之间的相互转换
 （Entity → VO）    .convert(testCase, TestCaseVO.class)
 （DTO → Entity）    .convert(testCaseDTO, TestCase.class)

 */
public class ConvertUtils {

    /**
     * 将源对象转换为目标类的新实例
     *
     * @param source      源对象（来自：DTO / Entity / VO）
     * @param targetClass 目标类（转换为：Entity / VO / DTO）
     * @param <T>         源类型
     * @param <V>         目标类型
     * @return 转换后的对象
     */
    public static <T, V> V convert(T source, Class<V> targetClass) {
        if (source == null) {
            return null;
        }

        try {
            // 创建目标对象实例（如 VO 或 Entity）
            V target = targetClass.getDeclaredConstructor().newInstance();

            // 执行字段拷贝（target 是目标对象，source 是源对象）
            BeanUtils.copyProperties(target, source);

            return target;
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException("对象转换失败: " + source.getClass() + " -> " + targetClass, e);
        }
    }

    /**
     * 批量转换列表（支持嵌套对象）
     *
     * @param sources     源对象列表（如 List<DTO>）
     * @param targetClass 目标类（如 TestPlan.class）
     * @param <T>         源类型
     * @param <V>         目标类型
     * @return 转换后的对象列表（如 List<Entity>）
     */
    public static <T, V> List<V> convertList(List<T> sources, Class<V> targetClass) {
        if (sources == null || sources.isEmpty()) {
            return Collections.emptyList();
        }

        return sources.stream()
                .map(source -> convert(source, targetClass))
                .collect(Collectors.toList());
    }

    /**
     * 带日志调试信息的转换方法（用于开发阶段排查字段映射问题）
     *
     * @param source      源对象
     * @param targetClass 目标类
     * @param logPrefix   日志前缀（用于标识当前是哪个转换）
     * @param <T>         源类型
     * @param <V>         目标类型
     * @return 转换后的对象
     */
    public static <T, V> V convertWithLog(T source, Class<V> targetClass, String logPrefix) {
        if (source == null) {
            return null;
        }

        try {
            V target = targetClass.getDeclaredConstructor().newInstance();
            logConversion(source, target, logPrefix);
            BeanUtils.copyProperties(target, source);
            return target;
        } catch (Exception e) {
            throw new RuntimeException(logPrefix + "对象转换失败: " + source.getClass() + " -> " + targetClass, e);
        }
    }

    /**
     * 打印转换前后的内容（便于调试）
     */
    private static <T, V> void logConversion(T source, V target, String logPrefix) {
        System.out.println(logPrefix + " - 开始转换:");
        System.out.println(logPrefix + " - Source: " + source);
        System.out.println(logPrefix + " - Target before copy: " + target);
    }

    /**
     * 判断一个对象是否为空（所有字段都为 null 或 empty）
     */
    public static boolean isEmpty(Object obj) {
        if (obj == null) return true;

        return Arrays.stream(obj.getClass().getDeclaredFields())
                .peek(f -> f.setAccessible(true))
                .allMatch(f -> {
                    try {
                        Object val = f.get(obj);
                        if (val instanceof String) {
                            return ((String) val).trim().isEmpty();
                        }
                        return val == null;
                    } catch (IllegalAccessException e) {
                        return true;
                    }
                });
    }
}
